package cc.rengu.igas.share.core.service.asyncall;

import cc.rengu.igas.momp.facade.response.ComboPaymentRefundResponse;
import cc.rengu.igas.momp.facade.result.Result;
import cc.rengu.oltp.service.base.DubboAsynBaseService;
import cc.rengu.oltp.service.common.constant.TreeNodeConstant;
import cc.rengu.oltp.service.common.dao.PayOrderInfoMapper;
import cc.rengu.oltp.service.common.dao.impl.PayOrderInfoMapperImpl;
import cc.rengu.oltp.service.common.entity.PayOrderInfo;
import cc.rengu.oltp.service.common.enums.BizStatusEnum;
import cc.rengu.oltp.service.common.enums.ChannelEnum;
import cc.rengu.oltp.service.common.enums.OltpRpcdEnum;
import cc.rengu.oltp.service.common.enums.TransStatusEnum;
import cc.rengu.oltp.service.model.BizException;
import cc.rengu.oltp.service.realize.OrderService;
import cc.rengu.oltp.service.realize.impl.OrderServiceImpl;
import cc.rengu.oltp.utility.annotation.BIZ_PROCESS;
import cc.rengu.oltp.utility.util.DateUtil;
import cc.rengu.oltp.utility.util.XmlTreeUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 营销商户手续费冲正异步处理结果
 */
public class AsynComboMchntFeeDiscReversalService extends DubboAsynBaseService {

    @BIZ_PROCESS
    public void comboMchntFeeDiscReversalResultDeal() throws Exception {

        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        String sysNo;
        String instId;
        if (!xmlTreeUtil.isExist(TreeNodeConstant.DUBBO_RESPONSE)) {
            rglog.error("dubbo调用营销商户手续费优惠冲正失败,抛出调用业务系统失败的异常，继续存储转发");
            throw new BizException(OltpRpcdEnum.CALL_BIZ_SERVICE_ERROR.getRespCode(), OltpRpcdEnum.CALL_BIZ_SERVICE_ERROR.getRespDesc());
        }

        rglog.debug("dubbo调用营销商户优惠手续费冲正-正常返回");
        Result<JSONObject> responseResult = (Result<JSONObject>) xmlTreeUtil.getXmlTreeObjectValue(TreeNodeConstant.DUBBO_RESPONSE, Result.class);
        if (!responseResult.isSuccess()) {
            rglog.error("dubbo调用营销商户手续费优惠冲正失败,抛出调用业务系统失败的异常，继续存储转发");
            throw new BizException(OltpRpcdEnum.CALL_BIZ_SERVICE_ERROR.getRespCode(), OltpRpcdEnum.CALL_BIZ_SERVICE_ERROR.getRespDesc());
        }

        ComboPaymentRefundResponse response = JSON.toJavaObject(responseResult.getResult(), ComboPaymentRefundResponse.class);
        /*避免支付成功发起记账跟查询交易发起记账系统流水号不一致的问题,取调用虚拟账户记账的traceNo*/
        if (response.getHeader() != null && response.getHeader().getTraceNo() != null) {
            sysNo = response.getHeader().getTraceNo().substring(0, 32);
            instId = xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.INST_ID);
        } else {
            rglog.error("dubbo调用营销商户手续费优惠冲正失败,抛出调用业务系统失败的异常，继续存储转发");
            throw new BizException(OltpRpcdEnum.CALL_BIZ_SERVICE_ERROR.getRespCode(), OltpRpcdEnum.CALL_BIZ_SERVICE_ERROR.getRespDesc());
        }

        /*获取支付订单列表*/
        rglog.info("根据流水号获取冲正交易中商户手续费优惠营销冲正的支付订单信息....");
        PayOrderInfoMapper payOrderInfoMapper = new PayOrderInfoMapperImpl();
        List<PayOrderInfo> payOrderInfoList = payOrderInfoMapper.selectPayOrderInfoBySysSeqNum(instId, sysNo);
        if (payOrderInfoList == null || payOrderInfoList.size() == 0) {
            rglog.error("根据机构号<{}>、系统流水号<{}>，获取支付订单列表失败", instId, sysNo);
            return;
        }

        /*获取营销手续费退回的支付订单*/
        List<PayOrderInfo> payOrderInfoListMomp = payOrderInfoList.stream().filter(item -> item.getMsgDstId().equals(ChannelEnum.MOMP.getChannelType())
                && "P04MO004".equals(item.getDstTxnNum())).collect(Collectors.toList());
        if (payOrderInfoListMomp.isEmpty()) {
            rglog.error("原交易没有调用营销手续费冲正");
            return;
        }
        PayOrderInfo payOrderInfo = payOrderInfoListMomp.get(0);
        rglog.trace("营销手续费优惠冲正支付订单信息:<{}>", JSONObject.toJSONString(payOrderInfo));

        OrderService orderService = new OrderServiceImpl();
        if (!OltpRpcdEnum.TRANS_SUCCESS.getRespCode().equals(response.getRespCode())) {
            rglog.warn("业务处理失败respCode<{}>,respDesc<{}>", response.getRespCode(), response.getRespDesc());
            /*若原支付订单业务状态不是处理,更新支付订单表失败*/
            if (BizStatusEnum.PROCESSING.getStatus().equals(payOrderInfo.getBizStatus())) {
                payOrderInfo.setTransStatus(TransStatusEnum.SYSTEM_REJECT.getStatus());
                payOrderInfo.setBizStatus(BizStatusEnum.FINISH.getStatus());
                payOrderInfo.setUpdateTime(DateUtil.getCurrentDateTime("yyyy-MM-dd HH:mm:ss.SSS"));
                if (!orderService.updateOrderInfo(null, null, payOrderInfo)) {
                    rglog.error("更新订单表状态失败");
                }
            } else {
                rglog.error("订单[{}]业务状态[{}]非业务处理中.不更新", payOrderInfo.getSysSeqNum(), payOrderInfo.getBizStatus());
            }
            return;
        }

        /*更新支付订单表成功*/
        rglog.info("营销冲正服务调用成功，更新营销手续费优惠冲正的支付订单表");
        payOrderInfo.setTransStatus(TransStatusEnum.TRANS_SUCC.getStatus());
        payOrderInfo.setBizStatus(BizStatusEnum.FINISH.getStatus());
        payOrderInfo.setUpdateTime(DateUtil.getCurrentDateTime("yyyy-MM-dd HH:mm:ss.SSS"));
        if (!orderService.updateOrderInfo(null, null, payOrderInfo)) {
            rglog.error("更新订单表状态失败");
        }

        /*获取原支付订单列表*/
        rglog.info("根据支付订单表中的原交易流水号获取原支付交易的商户优惠手续费支付订单信息,更新原支付交易业务状态为冲正");
        List<PayOrderInfo> oriPayOrderInfoList = payOrderInfoMapper.selectPayOrderInfoBySysSeqNum(instId, payOrderInfo.getOrigSysSeqNum());
        if (payOrderInfoList.size() == 0) {
            rglog.error("根据机构号<{}>、系统流水号<{}>获取原支付订单列表失败", instId, payOrderInfo.getOrigSysSeqNum());
            return;
        }
        List<PayOrderInfo> oriPayOrderInfoListMomp = oriPayOrderInfoList.stream().filter(item -> item.getMsgDstId().equals(ChannelEnum.MOMP.getChannelType())
                && "P01MO004".equals(item.getDstTxnNum())).collect(Collectors.toList());
        if (oriPayOrderInfoListMomp.isEmpty()) {
            rglog.error("原交易没有调用手续费营销,oriSysSeqNum:<{}>", payOrderInfo.getOrigSysSeqNum());
            return;
        }
        PayOrderInfo oriPayOrderInfoMomp = oriPayOrderInfoListMomp.get(0);
        oriPayOrderInfoMomp.setBizStatus(BizStatusEnum.REFUND.getStatus());
        if (!orderService.updateOrderInfo(null, null, oriPayOrderInfoMomp)) {
            rglog.error("更新订单表状态失败");
        }
    }
}
